package rrapi

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"time"
	"zimuzu_cvn_web_api/pkg/drive/redis"
	. "zimuzu_cvn_web_api/pkg/e"
)

const apiKey = "lQzl7TVycbpboiqNoWYi"
const apiDomain = "http://a.zmzapi.com"

//获取签名字符串
func GetSign(t string) string {

	return Sha1Str(Sha1Str(apiKey) + t)
}

//增加接口请求 认证字符串缓存
func AddConfirmU(u string) {
	redis.Set("public:rrapi:confirm:"+u, 1, 10)
}

//接口二次确认
func ApiConfirm(u string) bool {
	return redis.Exists("public:rrapi:confirm:" + u)
}

//检查账号是否存在
func CheckAccount(mobile string, area int) {

}

type UserinfoResponse struct {
	Status int        `json:"status"`
	Info   string     `json:"info"`
	Data   RRUserInfo `json:"data"`
}

type GetCodeOrderInfoResponse struct {
	Status int       `json:"status"`
	Info   string    `json:"info"`
	Data   CodeOrder `json:"data"`
}

type GetCodeListResponse struct {
	Status int       `json:"status"`
	Info   string    `json:"info"`
	Data   []VipCode `json:"data"`
}

type RRUserInfo struct {
	Uid         int64  `json:"uid"`
	PhoneArea   int    `json:"phone_area"`
	Password    string `db:"password" json:"password"`
	Email       string `db:"email,omitempty" json:"email"`
	Salt        string `db:"salt" json:"salt"`
	Nickname    string `json:"nickname"`
	PhoneNumber string `json:"phone_number"`
	UserPic     string `json:"userpic"`
	CreateTime  int64  `json:"create_time"`
}

type VipCode struct {
	Id         int64  `json:"id"`
	Code       string `json:"code"`
	CreateUid  int64  `json:"create_uid"`
	CreateTime int64  `json:"create_time"`
	VerifyUid  int64  `json:"verify_uid"`
	VerifyTime int64  `json:"verify_time"`
	OrderNum   string `json:"order_num"`
	Num        int64  `json:"type"`
	Period     int    `json:"period"`
	Source     int    `json:"source"`
	status     int    `json:"status"`
	saled      int    `json:"saled"`
}

type CodeOrder struct {
	Id         int64  `json:"id"`
	OrderNum   string `json:"order_num"`
	Uid        int64  `json:"uid"`
	Period     int    `json:"period"`
	TotalNum   int64  `json:"total_num"`
	CreateNum  int    `json:"create_num"`
	Status     int    `json:"status"`
	CreateTime int64  `json:"create_time"`
	UpdateTime int64  `json:"update_time"`
}

//获取账号信息
//Auth:Xu
func GetAccountInfo(mobile string, area int) (data RRUserInfo, err error) {
	var userinfoResponse UserinfoResponse
	timestr := strconv.FormatInt(time.Now().Unix(), 10)
	sign := GetSign(timestr)
	areaStr := strconv.Itoa(area)
	u := "userinfo" + mobile
	AddConfirmU(u)
	resp, err := http.Get(apiDomain + "/index.php?g=api/partner&m=cvnt&a=userinfo&area=" + areaStr + "&mobile=" + mobile + "&t=" + timestr + "&sign=" + sign + "&u=" + u)
	if err != nil {
		Log("err", err.Error())
		err = errors.New("查询主站用户信息失败")
		return
	}
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	json.Unmarshal(body, &userinfoResponse)

	if userinfoResponse.Status != 1 {
		err = errors.New("查询主站用户信息失败2")
		Log("err", userinfoResponse.Info)
		return
	}

	return userinfoResponse.Data, nil
}

type RegisterResponse struct {
	Status int    `json:"status"`
	Info   string `json:"info"`
	Data   struct {
		Uid int64 `json:"uid"`
	} `json:"data"`
}

//添加用户（注册）
//Auth:Xu
func AddUser(mobile, nickname string, area int, password string) (uid int64, err error) {
	var userinfoResponse UserinfoResponse
	timestr := strconv.FormatInt(time.Now().Unix(), 10)
	sign := GetSign(timestr)
	areaStr := strconv.Itoa(area)
	u := "register" + mobile
	AddConfirmU(u)
	values := url.Values{
		"area":       {areaStr},
		"mobile":     {mobile},
		"nickname":   {nickname},
		"sign":       {sign},
		"u":          {u},
		"password":   {password},
		"repassword": {password},
	}
	resp, err := postValue(apiDomain+"/index.php?g=api/partner&m=cvnt&a=register",
		values)
	if len(resp) == 0 {
		err = errors.New("站注册账号失败")
		return
	}
	json.Unmarshal([]byte(resp), &userinfoResponse)

	if userinfoResponse.Status != 1 {
		err = errors.New("主站注册账号失败2")
		Log("err", userinfoResponse.Info)
		return
	}

	return userinfoResponse.Data.Uid, nil
}

//修改密码
//Auth:Xu
func UpdatePassword(mobile string, area int, password string) (data RRUserInfo, err error) {
	var userinfoResponse UserinfoResponse
	timestr := strconv.FormatInt(time.Now().Unix(), 10)
	sign := GetSign(timestr)
	areaStr := strconv.Itoa(area)
	u := "update_password" + mobile
	AddConfirmU(u)

	values := url.Values{
		"area":     {areaStr},
		"mobile":   {mobile},
		"t":        {timestr},
		"sign":     {sign},
		"u":        {u},
		"password": {password},
	}
	resp, err := postValue(apiDomain+"/index.php?g=api/partner&m=cvnt&a=update_password",
		values)
	if len(resp) == 0 {
		err = errors.New("修改密码失败")
		return
	}
	json.Unmarshal([]byte(resp), &userinfoResponse)

	if userinfoResponse.Status != 1 {
		err = errors.New("修改密码失败2")
		Log("err", userinfoResponse.Info)
		return
	}

	return userinfoResponse.Data, nil
}

//升级码下单
//Auth：Xu
func CodeCreateOrder(uid int64, orderNo string, num int, period int) (err error) {
	var userinfoResponse RegisterResponse
	timestr := strconv.FormatInt(time.Now().Unix(), 10)
	uidstr := strconv.FormatInt(uid, 10)
	sign := GetSign(timestr)
	numStr := strconv.Itoa(num)
	periodStr := strconv.Itoa(period)
	u := "code_order" + uidstr
	AddConfirmU(u)

	values := url.Values{
		"uid":       {uidstr},
		"order_num": {orderNo},
		"t":         {timestr},
		"sign":      {sign},
		"u":         {u},
		"period":    {periodStr},
		"total_num": {numStr},
	}
	resp, err := postValue(apiDomain+"/index.php?g=api/partner&m=cvnt&a=code_order",
		values)
	if len(resp) == 0 {
		err = errors.New("创建订单失败失败")
		return
	}
	json.Unmarshal([]byte(resp), &userinfoResponse)

	if userinfoResponse.Status != 1 {
		err = errors.New("创建订单失败失败2")
		Log("err", userinfoResponse.Info)
		return
	}

	return nil
}

//获取用户升级码列表
//Auth：Xu
func GetCodeList(uid int64) (codelist []VipCode, err error) {
	var userinfoResponse GetCodeListResponse
	timestr := strconv.FormatInt(time.Now().Unix(), 10)
	uidstr := strconv.FormatInt(uid, 10)
	sign := GetSign(timestr)
	u := "code_list" + uidstr
	AddConfirmU(u)
	resp, err := http.Get(apiDomain + "/index.php?g=api/partner&m=cvnt&a=code_list" +
		"&uid=" + "&t=" + timestr + "&sign=" + sign + "&u=" + u)
	if err != nil {
		Log("err", err.Error())
		err = errors.New("查询升级码列表失败")
		return
	}
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	json.Unmarshal(body, &userinfoResponse)

	if userinfoResponse.Status != 1 {
		err = errors.New("查询升级码列表失败2")
		Log("err", userinfoResponse.Info)
		return
	}

	return userinfoResponse.Data, nil
}

//修改升级码售出状态
//Auth：Xu
func UpdateCodeSaleStatus(uid int64, code string) (err error) {
	var userinfoResponse UserinfoResponse
	timestr := strconv.FormatInt(time.Now().Unix(), 10)
	uidstr := strconv.FormatInt(uid, 10)
	sign := GetSign(timestr)
	u := "code_sale" + uidstr
	AddConfirmU(u)

	values := url.Values{
		"uid":  {uidstr},
		"code": {code},
		"t":    {timestr},
		"sign": {sign},
		"u":    {u},
	}
	resp, err := postValue(apiDomain+"/index.php?g=api/partner&m=cvnt&a=code_sale",
		values)
	if len(resp) == 0 {
		err = errors.New("标记失败2")
		return
	}
	json.Unmarshal([]byte(resp), &userinfoResponse)

	if userinfoResponse.Status != 1 {
		err = errors.New("标记失败2")
		Log("err", userinfoResponse.Info)
		return
	}

	return nil
}

//获取升级码订单信息
//Auth：Xu
func GetCodeOrderInfo(uid int64, orderNum string) (orderInfo CodeOrder, err error) {
	var response GetCodeOrderInfoResponse
	timestr := strconv.FormatInt(time.Now().Unix(), 10)
	uidstr := strconv.FormatInt(uid, 10)
	sign := GetSign(timestr)
	u := "code_order_info" + uidstr
	AddConfirmU(u)
	resp, err := http.Get(apiDomain + "/index.php?g=api/partner&m=cvnt&a=code_order_info" +
		"&uid=" + uidstr + "&order_num=" + orderNum + "&t=" + timestr + "&sign=" + sign + "&u=" + u)
	if err != nil {
		Log("err", err.Error())
		err = errors.New("获取升级码订单信息失败")
		return
	}
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	json.Unmarshal(body, &response)

	if response.Status != 1 {
		err = errors.New("获取升级码订单信息失败")
		Log("err", response.Info)
		return
	}

	return response.Data, nil
}

func postValue(host string, values url.Values) (data string, err error) {
	resp, err := http.PostForm(host, values)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return
	}

	return string(body), nil
}
